package com.harzone.commons.search.impl.maker;

import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.solr.client.solrj.response.Group;
import org.apache.solr.client.solrj.response.GroupCommand;
import org.apache.solr.client.solrj.response.GroupResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.harzone.commons.search.domain.AFunctions;
import com.harzone.commons.search.domain.Field;
import com.harzone.commons.search.domain.MethodField;
import com.harzone.commons.search.domain.Record;
import com.harzone.commons.search.impl.domain.Constant;
import com.harzone.commons.search.result.SearchResult;
import com.harzone.commons.search.result.SearchResultSet;
import com.harzone.commons.search.statement.Select;

public class SearchResultMaker {
	
	protected static Logger logger = LoggerFactory.getLogger(SearchResultMaker.class);
	
	private static final List<String> exceptField = new ArrayList<String>();
	static{
		exceptField.add(Constant.VERSION_FILED);
		exceptField.add(Constant.SCORE_FILED);
	}
	
	
	public static Record makeRecord(SearchResultSet resultSet) throws SQLException{
		Record  record = null;
		record = new Record();
		ResultSetMetaData  metaData = resultSet.getMetaData();
		int columnCount = metaData.getColumnCount();
		int index = 0;
		while(columnCount>index){
			String name = metaData.getColumnName(index+1);
			Object value = resultSet.getObject(index);
			record.addField(name, value);
			index++;
		}
		return record;
	}
	
	
	/**
	 * 处理查询结果
	 * @author ls
	 * 2014年11月22日下午4:14:26 
	 * @param dlist
	 * @param select
	 * @return
	 */
	public static SearchResult makeResult(final SolrDocumentList dlist, final Select select){
		
		List<Field> list = null;
		if(select!=null){
			 list = select.getFields();
		}
		boolean showAll = false, isAgg = false;
		Field field = null;
		if(list !=null && !list.isEmpty()){
			int index = list.size();
			if(index==1){
				field = list.get(0);
				if (field instanceof MethodField) {
					 isAgg = true;
				}else{
					if(field.isShowAll()){
						showAll = true;
					}
				}
			}
		}else{
			showAll = true;
		}
		SearchResult result = new SearchResult(dlist.getNumFound());
		result.setMaxScore(dlist.getMaxScore());
		if(!isAgg){
			result = handlResult(result,dlist, showAll, list);
		}else{
			result.add(handlAggRecord(dlist, field));
		}
		return result;
	}

	
	/**
	 * 处理聚合函数结果
	 * @author ls
	 * 2014年11月24日下午2:36:09 
	 * @param record
	 * @param dlist
	 * @param field
	 * @return
	 */
	private static Record handlAggRecord(final Record  record, final SolrDocumentList dlist, final Field field){
		AFunctions af =	AFunctions.get(field.getName());
		switch(af){
			case AVG:
				break;
			case COUNT:
				record.addField(field.getName(), dlist.getNumFound());
				break;
			case MAX:
				break;
			case MIN:
				break;
			case SUM:
				break;
			case TOPHITS:
				break;
			case UNKWON:
			default:
				break;
		}
		return record;
	}
	
	/**
	 * 处理聚合函数结果
	 * @author ls
	 * 2014年11月24日下午2:36:27 
	 * @param dlist
	 * @param field
	 * @return
	 */
	private static Record handlAggRecord(final SolrDocumentList dlist, final Field field){
		Record  record = null;
		record = new Record();
		return handlAggRecord(record, dlist, field);
	}

	 
	/**
	 * 处理结果
	 * @author ls
	 * 2014年11月24日下午2:36:31 
	 * @param result
	 * @param dlist
	 * @param showAll
	 * @param list
	 * @return
	 */
	private static SearchResult handlResult(final SearchResult result, final SolrDocumentList dlist
			, final boolean showAll, final List<Field> list){
		final List<String> fields = new ArrayList<String>();
		for (SolrDocument solrDocument : dlist) {
			result.add(handRecord(solrDocument, showAll, list, fields));
		}
		fields.clear();
		return result;
	}
	
	private static boolean isExcept(String name){
		for (String string : exceptField) {
			if(string.equals(name)){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 处理单条记录结果
	 * @author ls
	 * 2014年11月24日下午2:36:40 
	 * @param solrDocument
	 * @param showAll
	 * @param list
	 * @return
	 */
	private static Record handRecord(final SolrDocument solrDocument
			, final boolean showAll, final List<Field> list
			, final List<String> fields ){
		Record  record = null;
		record = new Record();
		Object value = null;
		if(showAll){
			if(fields.isEmpty()){
				Collection<String> names = solrDocument.getFieldNames();
				for (String name : names) {
					if(!isExcept(name)){
						value = solrDocument.getFieldValue(name);
						record.addField(name, value);
						fields.add(name);
					}
				}
			}else{
				for (String string : fields) {
					value = solrDocument.getFieldValue(string);
					record.addField(string, value);
				}
			}
		}else{
			for (Field f : list) {
				value = solrDocument.getFieldValue(f.getIndexName());
				record.addField(f.getName(), value);
			}
		} 
		if(solrDocument.containsKey(Constant.VERSION_FILED)){
			record.setVersion(Long.valueOf(String.valueOf(solrDocument.getFieldValue(Constant.VERSION_FILED))));
		}
		if(solrDocument.containsKey(Constant.SCORE_FILED)){
			record.setScore(Float.valueOf(String.valueOf(solrDocument.getFieldValue(Constant.SCORE_FILED))));
		}
		return record;
	}
	
	
	/**
	 * 处理分组结果
	 * @author ls
	 * 2014年11月24日下午1:23:26 
	 * @param groupResponse
	 * @param select
	 * @return
	 */
	public static SearchResult makeGroupResult(final GroupResponse groupResponse, final Select select){
		SearchResult result = new SearchResult(); 
		final List<GroupCommand> groupCommandList = groupResponse.getValues();  
		final List<Field> list = select.getFields();
		boolean showAll = false;
		if(list !=null && !list.isEmpty()){
			int index = list.size();
			if(index==1){
				Field field = list.get(0);
				if (!(field instanceof MethodField)) {
					if(field.isShowAll()){
						showAll = true;
					}
				}
			}
		}else{
			showAll = true;
		}
        for (GroupCommand groupCommand : groupCommandList) {  
//        	System.out.println("GroupCommand Name : " + groupCommand.getName());  
//            System.out.println("Num of Groups Found: " + groupCommand.getNGroups());  
//            System.out.println("Num of documents Found: " + groupCommand.getMatches());  
//
//            System.out.println("The groups are: ");  
        	result.setTotal(groupCommand.getNGroups());
            List<Group> groups = groupCommand.getValues();  
            Record  record = null;
            for (Group group : groups) {  
                SolrDocumentList dlist = group.getResult();  
                /*System.out.println("group value: " + group.getGroupValue());  
                System.out.println("solrDocumentList.size():"+solrDocumentList.size());
                System.out.println("Num of Documents in this group: " + solrDocumentList.getNumFound());  
                System.out.println("start: " + solrDocumentList.getStart());  
                System.out.println("Max score: " + solrDocumentList.getMaxScore()); */
        		record = new Record();
                if(select.isAgg){
                	for (Field field : list) {
                		handlAggRecord(record,dlist, field);
                	}
                	result.add(record);
                }else{
                	handlResult(result,dlist, showAll, list);
                }
            }
            //目前只支持单个分组条件
            break;
        }
        return result;
	}
 
}
